/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.messaging.inbox;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import javax.swing.ImageIcon;
import nl.cloudfarming.client.logging.AppLogFactory;
import nl.cloudfarming.client.logging.AppLogger;
import nl.cloudfarming.client.messaging.Message;
import nl.cloudfarming.client.messaging.MessageModule;

import nl.cloudfarming.eventbus.GuiEvent;
import org.openide.awt.Notification;
import org.openide.awt.NotificationDisplayer;
import org.openide.util.NbBundle;

/**
 * Wrapperclass to show the NotificationDisplayer when GuiEvent for a new incoming Message is triggered.
 * Keep track of messages and their notifications to purge the notification from the list if the message has been read.
 * 
 * @author Gerben Feenstra
 */
public class MessageNotifier {

    // Keep track of messages and their notifications to purge the notification from the list if the corresponding message has been read.
    private static HashMap<Message, Notification> activeNotifications = new HashMap<Message, Notification>();
    private static final AppLogger LOG = AppLogFactory.getLogger(MessageModule.class);
    private static final String DATE_FORMAT = NbBundle.getMessage(MessageModule.class, "messaging.message.datereceived.format");

    // Service providers must have a public no-arg constructor
    public MessageNotifier() {
    }

    /**
     * A message has been read and the notification belonging to that message can be cleared and removed.
     * If the event contains a message for which there is no notifier nothing will happen.
     * 
     * @param event Event fired by the GuiEventBus containing the message
     */
    void removeNotifier(GuiEvent<Message> event) {
        final Message message = event.getContent();

        //Log
        StringBuilder logSb = new StringBuilder();
        logSb.append("Message with id ");
        logSb.append(message.getId());
        logSb.append(" has been read. Removing notification from list.");
        LOG.info(logSb.toString());

        Notification notificationToDisable = activeNotifications.get(message);
        if (notificationToDisable != null) {
            notificationToDisable.clear();
            activeNotifications.remove(message);
        } else {
            // Log error
            StringBuilder logErrorSb = new StringBuilder();
            logErrorSb.append("This message (");
            logErrorSb.append(message.getId());
            logErrorSb.append(")  has no notifier or a null notifier object.");
            LOG.error(logErrorSb.toString());
        }
    }

    /**
     * Retrieve Message from event and show the NotificationDisplayer with the message-info provided.
     * Clicking the notifier-balloon will open the inbox topcomponent
     * @param event Event fired by the GuiEventBus.
     */
    void showNotifier(GuiEvent<Message> event) {
        final Message message = event.getContent();

        // Log
        StringBuilder logSb = new StringBuilder();
        logSb.append("Message with id ");
        logSb.append(message.getId());
        logSb.append("received. Displaying notification.");
        LOG.info(logSb.toString());

        Format formatter = new SimpleDateFormat(DATE_FORMAT);
        String receiveDate = formatter.format(message.getDateReceived());

        StringBuilder dateSb = new StringBuilder();
        dateSb.append(receiveDate);
        dateSb.append(" - ");
        // Who/what send the message?
        dateSb.append(NbBundle.getMessage(MessageModule.class, "messaging.message.origin.label.text", message.getOrigin()));

        // Subject as clickable part of the notifier
        String clickable = NbBundle.getMessage(MessageModule.class, "messaging.messagenotifier.notification.text.clickable", message.getTitle());

        Notification notification = (Notification) NotificationDisplayer.getDefault().notify(dateSb.toString(), new ImageIcon(), clickable, new ActionListener() {

            // Define action when balloon is clicked
            @Override
            public void actionPerformed(ActionEvent e) {
                // Goto MessagePopup
                MessageDisplayFrame messagePopUp = new MessageDisplayFrame(message);
                messagePopUp.setVisible(true);

            }
        });
        activeNotifications.put(message, notification);
    }

    /**
     * Indicate if a notification belonging to the specified message is still active
     * @param message 
     */
    public static boolean isActive(Message message) {
        if (activeNotifications.containsKey(message)) {
            return true;
        }
        return false;
    }
}
